package com.chenjun.designpattern.behavior.strategy;

/**
 * @author Administrator
 *         <h1>策略模式定义:
 *         <h1>策略模式定义了一系列的算法，并将每一个算法 (作为类) 封装起来，
 *         而且使它们还可以相互替换，策略模式让算法独立于使用它的客户而独立变化。 策略模式使这些算法在客户端调用它们的时候能够互不影响地变化。
 * 
 *         <p>
 *         策略模式的意义:
 *         <p>
 *         策略模式使开发人员能够开发出由许多可替换的部分组成的软件，并且各个部分之间是低耦合的关系。<br/>
 *         低耦合的特性使软件具有更强的可扩展性，易于维护；更重要的是，它大大提高了软件的可重用性
 * 
 *         <p>
 *         策略模式中有三个对象： 环境对象或者成为上下文对象(Context)：该类中实现了对抽象策略中定义的接口或者抽象类的引用。
 *         抽象策略对象(Strategy)：它可由接口或抽象类来实现。
 *         具体策略对象(ConcreteStrategy)：它封装了实现同不功能的不同算法。
 */
public class 策略模式
{
	public static void main(String[] args)
	{
		// 加法
		Context<Integer,Integer,Integer> context = new Context<Integer,Integer,Integer>(new AddStrategy());
		System.out.println(context.algorithm(147970, 116565));
		// 减法
		Context<Integer,Integer,Integer> context2 = new Context<Integer,Integer,Integer>(new SubStrategy());
		System.out.println(context2.algorithm(243213, 21322));
		// 乘法
		Context<Long,Integer,Integer> context3 = new Context<Long,Integer,Integer>(new MultiplyStrategy());
		System.out.println(context3.algorithm(626, 878));
		// 除法
		Context<Double,Integer,Integer> context4 = new Context<Double,Integer,Integer>(new DivisionStrategy());
		System.out.println(context4.algorithm(90, 14));
	}
}

/**
 * 
 * @author Administrator
 *
 * @param <T> 返回值
 * @param <O1>操作数1
 * @param <O2>
 */
class Context<T,O1,O2>
{
	private Strategy<T,O1,O2> strategy;

	public Context(Strategy<T,O1,O2> strategy)
	{
		super();
		this.strategy = strategy;
	}

	/**
	 * getter and setter
	 * 
	 * @return
	 */
	public Strategy<T,O1,O2> getStrategy()
	{
		return strategy;
	}

	public void setStrategy(Strategy<T,O1,O2> strategy)
	{
		this.strategy = strategy;
	}
	
	public T algorithm(O1 a,O2 b)
	{
		return strategy.algorithm(a, b);
	}
}

abstract class Strategy<T,O1,O2>
{
	public abstract T algorithm(O1 a, O2 b);
}

/**
 * 实现加法运算
 * 
 * @author Administrator
 */
class AddStrategy extends Strategy<Integer,Integer,Integer>
{
	@Override
	public Integer algorithm(Integer a, Integer b)
	{
		return a + b;
	}
}

/**
 * 实现加法运算
 * 
 * @author Administrator
 */
class SubStrategy extends Strategy<Integer,Integer,Integer>
{
	@Override
	public Integer algorithm(Integer a, Integer b)
	{
		return a - b;
	}
}

/**
 * 实现X法运算
 * 
 * @author Administrator
 */
class MultiplyStrategy extends Strategy<Long,Integer,Integer>
{
	@Override
	public Long algorithm(Integer a, Integer b)
	{
		return (long)a*b;
	}
}

/**
 * 实现÷法运算
 * 
 * @author Administrator
 */
class DivisionStrategy extends Strategy<Double,Integer,Integer>
{
	@Override
	public Double algorithm(Integer a, Integer b)
	{
		return (double)a/b;
	}
}
